//给路径集合创建树关联的逻辑：
//1、通过迭代获取次级目录，路径作为键（包括父键），添加是否为指定类型文件的标记位
//2、根据key去重合再递归并为树
/**
 * 指定后缀文件路径集合转换为树结构
 *
 * @param {Array} arr 路径集合
 * @param {String} postfix 后缀
 * @return {Object} 树结构 {key,path,name,level,parentKey,children,isFile}
 */
const filePathsToTree = (arr, postfix) => {
  if (arr.length && arr.length > 0) {
    let paths = []
    arr.forEach(element => {
      //拆分节点
      let pathItems = element.split('/');
      let oldNode = {}
      const addPaths = (pathItems, index) => {
        if (index >= pathItems.length) return;
        let name = '';
        for (let i = 0; i <= index; i++) {
          name += ((i == 0 ? '' : '/') + pathItems[i]);
        }
        let node = {
          key: name,
          path: name,
          name: pathItems[index],
          level: index,
          parentKey: oldNode.key,
          isFile: name.indexOf(postfix) > -1
        }
        oldNode = node
        paths.push(node);
        if (index < pathItems.length) {
          addPaths(pathItems, index + 1);
        }
      }
      addPaths(pathItems, 0)

    })
    //去重复
    const unique = (arr, key) => {
      let result = {};
      for (let item of arr) {
        result[item[key]] = item;
      }
      return Object.values(result); // 再转化为数组
    }
    paths = unique(paths, 'key')
    //合并为树
    let tempArray = [];
    paths.forEach((item) => {
      tempArray.push([item.key, { ...item }]); // 转化成Map结构，通过键名查找score
    })
    let scoreMap = new Map(tempArray);
    let rootNode = scoreMap.get('.');
    rootNode.children = []
    const setChildren = (value) => {
      if (value.isFile) return value;
      if (!value.children) value.children = []
      scoreMap.forEach((value2) => {
        if (scoreMap.has(value2.parentKey)) {
          let parent = scoreMap.get(value2.parentKey)
          if (parent.key == value.key) {
            value.children.push(setChildren(value2));
          }
        }
      })
      return value;
    }
    rootNode = setChildren(rootNode);
    return rootNode;
  }
}

/**
 * 给树设置键
 * @param {Object} tree 树对象
 */
const setTreeKey = (tree) => {
  if (tree) {
    let defaultKey = '0';
    const setChildrenKey = (obj, prefix) => {
      let tr = obj;
      if (tr.children && tr.children.length) {
        for (let i = 0; i < tr.children.length; i++) {
          tr.children[i].key = prefix + '-' + i;
          if (tr.children[i].children && tr.children[i].children.length) {
            tr.children[i] = setChildrenKey(tr.children[i], tr.children[i].key);
          }
        }
        return tr;
      }
      else {
        return tr;
      }
    }
    if (Array.isArray(tree)) {
      for (let i = 0; i < tree.length; i++) {
        tree[i] = setChildrenKey(tree[i], defaultKey)
      }
      return tree
    }
    else {
      tree.key = defaultKey;
      tree = setChildrenKey(tree, defaultKey);
      return tree
    }
  }
  else {
    return {}
  }
}

/**
 * 查找树中第一个某字段包含指定值值的成员
 * @param {Object} obj 树对象
 * @param {String} fieldName 字段名
 * @param {Object} value 值
 */
const findFirstFieldvalueInTree = (obj, fieldName, value) => {
  if (obj[fieldName] == value) {
    return obj;
  }
  else if (obj.children && obj.children.length) {
    //一个简单记录，基础知识点，数组forEach是异步迭代操作，不能通过return进行控制中断
    for (let i = 0; i < obj.children.length; i++) {
      let element = obj.children[i];
      if (element[fieldName] == value || element.children && element.children.length) {
        return findFirstFieldvalueInTree(element, fieldName, value);
      }
    }
  }
  return obj;
}

export { filePathsToTree, setTreeKey, findFirstFieldvalueInTree }